package sms

import (
	"errors"
	"fmt"
	openapi "github.com/alibabacloud-go/darabonba-openapi/client"
	dysmsapi20170525 "github.com/alibabacloud-go/dysmsapi-20170525/v2/client"
	"github.com/alibabacloud-go/tea/tea"
	"cgs-server/server"
	"cgs-server/server/base"
	"cgs-server/server/store/sms"
	"sync"
)

// 短信服务
// dbOnce 保证获取实例时的线程安全
var smsOnce sync.Once

var smsClient *dysmsapi20170525.Client

/**
 * 使用AK&SK初始化账号Client
 * @param accessKeyId
 * @param accessKeySecret
 * @return Client
 * @throws Exception
 */
func CreateClient () (*dysmsapi20170525.Client, error) {
	var err error
	if server.Config.Sms.AccessKeyId == "" || server.Config.Sms.AccessKeySecret == "" {
		err = errors.New("accessKeyId and accessKeySecret is required")
		return smsClient, err
	}

	smsOnce.Do(func() {
		config := &openapi.Config{
			// 您的AccessKey ID
			AccessKeyId: tea.String(server.Config.Sms.AccessKeyId),
			// 您的AccessKey Secret
			AccessKeySecret: tea.String(server.Config.Sms.AccessKeySecret),
		}
		// 访问的域名
		config.Endpoint = tea.String("dysmsapi.aliyuncs.com")
		smsClient, err = dysmsapi20170525.NewClient(config)
	})

	return smsClient, err
}



// 发送验证码
func SendValidationCode(phoneNumber string) error {
	client, _err := CreateClient()
	if _err != nil {
		return _err
	}

	code := base.GenerateTenantId()
	param := fmt.Sprintf("{%s:%s}", server.Config.Sms.VerificationTemplateParam, code)

	//fmt.Println(param) // {code:855998}

	sendSmsRequest := &dysmsapi20170525.SendSmsRequest{
		PhoneNumbers: tea.String(phoneNumber),
		SignName: tea.String(server.Config.Sms.SignName),
		TemplateCode: tea.String(server.Config.Sms.VerificationTemplateCode),
		TemplateParam: tea.String(param),
	}
	// 复制代码运行请自行打印 API 的返回值
	_result, _err := client.SendSms(sendSmsRequest)
	if _err != nil {
		return _err
	}
	if *_result.Body.Code != "OK" {
		return errors.New(*_result.Body.Message)
	}

	// 存入数据库，超时时间为 5min
	_err = sms.UpdateSmsCode(&sms.Sms{
		PhoneNumber: phoneNumber,
		Code:        code,
	})

	return nil
}

// 校验验证码
func CheckValidationCode(phoneNumber, validationCode string) error {
	smsCode, _ := sms.GetSmsCode(phoneNumber)
	if smsCode == nil || smsCode.IsExpired() {
		return errors.New("验证码已过期，请重新发送。")
	}

	if smsCode.Code != validationCode {
		return errors.New("验证码不正确")
	}

	return nil
}
